_Pragma("once");

#include <string>
#include <ctime>

#include "DateTimeUtility.h"
#include "ConfigManager.h"
#include "LoopStatus.h"
#include "SingletonTemplate.h"
#include "LoopControlInfo.h"
#include "VideoPlayInfo.h"
#include "FileDownloader.h"
#include "LoopScheduler.h"
#include "IotGatewayInfo.h"

class CommandParser;
class LoopManager;
class LoopScheduler;
class UriInfo;

/**
 * 与服务器指令交互的处理接口
 *
 * @author lizb
 */
class CommandExecutor {
    friend class SingletonTemplate<CommandExecutor>;
public:

    CommandExecutor();

    /**
    * A指令 写入特定时间段内的开关操作
    *
    * @param conn 当前连接
    * @param detailCmd, std::string& result 指令内容
    */
    void onSpecialTimeOperated(std::string& detailCmd, std::string& result);

    /**
     * B指令 申请本地储存数据操作
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onRequestOfflineCommand(const std::tm dateTime, std::string& result);

    /**
     * C指令 写入备选IP地址和端口号
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onWriteBackupServerPort(const std::string& detailCmd, std::string& result) {};

    /**
     * D指令 删除本地开关操作存储
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onDeleteLocalSwitch(std::string& result);

    /**
     * E指令 设置当天定时器指令
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onTodayTimer(const std::string& detailCmd, std::string& result) {};

    /**
     * F指令 获取经纬度
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onNewRequestLocation(const std::string& detailCmd, std::string& result);


    /**
     * G指令 获取经纬度
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onRequestLocation(const std::string& detailCmd, std::string& result) {};

    /**
     * H指令 写入系统时间
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onWriteTime(const NetworkStringView& detailCmd);

    /**
     * I指令  读取系统时间
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onReadTime(std::string& result) {
        tm nowTm = DateTimeUtility::getTime();
        result.resize(14);
        strftime(&result[0], result.size() + 1, DateTimeUtility::DATE_TIME_FORMAT.c_str(), &nowTm);

    }

    /**
     * J指令 用于查询开关状态
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onCheckSwitch(std::string& result);

    /**
     * K指令 操作16路开关
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onChannelOperated(LoopControlInfoPtr command, const std::time_t delaySeconds, std::string& result);

    /**
     * L指令获取通道数
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    size_t onChannel();


    /**
     * m指令强行将手动状态切换到自动状态
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onOperatedState(const std::string& detailCmd, std::string& result) {};
    /**
     * N指令 获取其他回路的电压电流信息
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onExtendCurrentAndVoltage(const std::string& detailCmd, std::string& result) {};

    /**
     * O指令获取们的开关状态
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void  onDoorStatus(const std::string& detailCmd, std::string& result);

    /**
     * p指令获取光照强度
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onSunLight(const std::string& detailCmd, std::string& result);

    /**
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onNetworkState(const std::string& detailCmd, std::string& result);

    /**
     * T指令读取终端工作环境温度
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onTemperature(const std::string& detailCmd, std::string& result);

    /**
     * U指令获取回路电流电压
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onCurrentAndVoltage(const std::string& detailCmd, std::string& result);

    /**
     * V指令获取系统软件版本号
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onVersion(std::string& result);

    /**
     * W指令获取功率
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onPower(const std::string& detailCmd, std::string& result);

    /**
     * X指令 获取deviceId
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onRequestDeviceId(std::string& result);


    /**
     * Y指令获取湿度指令
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onHumidity(const std::string& detailCmd, std::string& result) {};

    /**
     * Z指令模拟按键
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void simulatorKeyPress(const std::string& detailCmd, std::string& result) {};

    /**
     * p指令，测试服务器时延g
     *
     * @param conn 当前连接
     * @param detailCmd, std::string& result 指令内容
     */
    void onPingBack(const std::string& detailCmd, std::string& result) {};

    void notImplemented(const std::string& detailCmd, std::string& result) {};


    void onAcSwitchStatus(std::string& switchMode, std::string& loopSwitchStatus);

    void onVideoControl(VideoPlayInfo& videoPlayInfo, std::string& result);


    void onDownloadFile(const UriInfo& uriInfo, std::string& result);


    bool updateFirmware(FileDownloader& downloader, const std::string& pathname);

    void setSystemTime(std::tm& tmTime);


    void lock(std::string& result);

    void unlock(const std::time_t delaySeconds, std::string& result);

    void updatePassword(const std::string password, std::string& result);


    void onExtendDeviceStatus(std::vector<ExtendDeviceInfo>& result);

    void onForwardData(const VerbInfo& verbInfo,  VerbResult& result);


    LoopManager& mloopManager;
//    LoopScheduler& mloopScheduler{LoopSchedulerSingleton::instance()};

    ConfigManager& mconfigManager = ConfigManagerSingleton::instance();

    CommandParser* mparentCommandParser;

    FileDownloader* volatile mpFileDownloader;
};


using CommandExecutorSingleton = class SingletonTemplate<CommandExecutor>;
